#include <iostream>
#include <vector>
#include <queue>

using namespace std;

const int INF = 1e9;

struct Edge {
    int to, cost;
};

int prim(vector<vector<Edge>>& graph, int n) {
    vector<int> dist(n, INF); 
    vector<bool> visited(n, false); 
    int minCost = 0; 

    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

    dist[0] = 0;
    pq.push(make_pair(0, 0));

    while (!pq.empty()) {
        int u = pq.top().second; 
        pq.pop();

        if (visited[u]) {
            continue;
        }

        visited[u] = true; 
        minCost += dist[u]; 

        for (auto& edge : graph[u]) {
            int v = edge.to;
            int cost = edge.cost;

            if (!visited[v] && cost < dist[v]) {
                dist[v] = cost;
                pq.push(make_pair(dist[v], v));
            }
        }
    }

    return minCost;
}

int main() {
    int n; 
    cout << "请输入点的数量：";
    cin >> n;

    vector<vector<Edge>> graph(n, vector<Edge>());

    cout << "请依次输入各个点之间的距离：" << endl;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int cost;
            cin >> cost;

            if (i != j) {
                graph[i].push_back({j, cost});
            }
        }
    }

    int minCost = prim(graph, n);

    cout << "连接所有点的最小费用为：" << minCost << endl;

    return 0;
}